<?php


namespace app\common\model;


use think\Cache;
use think\Db;
use think\Exception;

class FamilyTree extends BaseModel{

    protected $updateTime = false;
    protected static $treeCache = 'tree_cache%s';
    protected static $arr = [];
    protected $append = [
        'end_status'
    ];

    public function family(){
        return $this->hasOne('FamilyTree','spouse_id','id')->alias('fm');
    }

    public function user(){
        return $this->belongsTo('User','user_id','id')->field('id,nickname,avatar,gender,level,bio,score,die_time,birthday,reward,education');
    }

    public function getEndStatusAttr($value,$data){
        if($data['end_time']){
            $time = strtotime($data['end_time']);
            if($time <= time()){
                return 1;
            }
        }
        return 0;
    }

    /**
     * 验证是否存在家庭树
     * @param $userId
     * @return bool
     * @throws \think\Exception
     */
    public static function checkTree($userId){
        $count = self::where('user_id',$userId)->count();
        if($count > 0){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 查询家庭树状结构，无限级
     * @param $familyId
     * @return array|false|\PDOStatement|string|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getFamilyList($familyId){
        $p = self::where('family_id',$familyId)->where('parent_id',0)->where('gender',1)->where('is_max',1)->field('id,name,spouse_id,gender,seniority,end_time')->find();
        if(empty($p)){
            return self::where('family_id',$familyId)->where('parent_id',0)->where('gender',0)->order('start_time','asc')->field('id,name,spouse_id,gender,seniority,end_time')->find();
        }
        self::$arr[] = 1;
        $p->daishu = 1;
        return self::dgFamily($p,1);
    }

    /**
     * 递归查询数据
     * @param $p
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function dgFamily($p,$n){
        if(empty($p)){
            return [];
        }
        $p = $p->toArray();
        $p['spouse'] = self::where('id',$p['spouse_id'])->field('id,name,spouse_id,gender,end_time')->find();
        $spouseId = empty($p['spouse']) ? $p['id'] : $p['spouse']['id'];
        $child = self::where('parent_id','IN',[$p['id'],$spouseId])->field('id,name,spouse_id,gender,seniority,end_time')->order('start_time','asc')->select();
        if($child->isEmpty()){
            return $p;
        }
        $num = self::$arr[count(self::$arr) - 1]  + 1;
        $n2 = $n + 1;
        // 如果出现女儿，那么这条线不递归查下去了。只查女儿下一级
        if($p['gender'] == 0){
            foreach($child as $k=>$v){
                //if($v['id'] == 203){
                //    echo '<pre>';print_r(self::$arr);die;
                //}
                if(in_array($n2,self::$arr)){
                    unset($v['seniority']);
                }else{
                    self::$arr[] = $num;
                    $v->daishu = $n2;
                }
                $cp = self::where('id',$v['spouse_id'])->find();
                $p['child'][$k] = $v;
                $p['child'][$k]['spouse'] = $cp;
            }
            return $p;
        }

        foreach($child as $k=>$v){
            if(in_array($n2,self::$arr)){
                unset($v['seniority']);
            }else{
                $v->daishu = $n2;
                self::$arr[] = $num;
            }
            $p['child'][] = self::dgFamily($v,$n2);
        }
        return $p;
    }


    /**
     * 获取缓存数据
     * @param $familyId
     * @return mixed
     */
    public static function getTree($familyId){
        $key = sprintf(self::$treeCache,$familyId);

        if(!Cache::has($key) || config('app_debug')){
            Cache::set($key,self::getFamilyList($familyId),0);
        }
        return Cache::get($key);
    }

    /**
     * 删除缓存
     * @param $familyId
     * @return false|int
     */
    public static function delCache($familyId){
        $key = sprintf(self::$treeCache,$familyId);
        return Cache::rm($key);
    }

    public static function updateInfo($family,$update){
        $result = self::where('id',$family['id'])->update($update);
        if($family['user_id'] != 0){
            // 修改个人中心信息
            User::where('id',$family['user_id'])->update([
                'nickname'  => $update['name'],
                'seniority' => $update['seniority'],
                'birthday'  => $update['start_time'],
                'die_time'  => $update['end_time']
            ]);
        }
        return $result;
    }

    /**
     * 通过申请
     * @param $type 类型:1=通过,2=拒绝
     * @param $familyInfo 用户家庭信息
     * @param $applyInfo    申请信息
     * @return bool
     */
    public static function apply($type,$familyInfo,$applyInfo){
        Db::startTrans();
        try{
            // 通过审核
            if($type == 1){
                $applyFamilyInfo = self::where('id',$applyInfo['apply_f_id'])->field('id,family_id')->find();
                // 获取申请人家庭最上级信息
                $topLevelId = self::where('family_id',$applyFamilyInfo['family_id'])->where('parent_id',0)->where('gender',1)->where('is_max',1)->value('id');
                if(empty($topLevelId)){
                    $topLevelId = self::where('family_id',$applyFamilyInfo['family_id'])->where('parent_id',0)->where('gender',0)->order('start_time','asc')->value('id');
                }
                if(empty($topLevelId)){
                    throw new Exception('家庭上级id查询失败,apply_f_id:'.$applyInfo['apply_f_id']);
                }
                // 删除原家庭 家族群聊信息
                $applyUserId = self::where('family_id',$applyFamilyInfo['family_id'])->where('user_id','<>',0)->column('user_id');
                RoomUser::where('user_id','IN',$applyUserId)->where('types',2)->delete();

                // 加入新家族群聊
                $familyUserIds = self::where('family_id',$familyInfo['family_id'])->where('user_id','<>',0)->column('user_id');
                $roomId = RoomUser::where('user_id','IN',$familyUserIds)->where('types',2)->value('room_id');
                if(!empty($roomId)){
                    $createData = [];
                    foreach($applyUserId as $v){
                        $createData[] = [
                            'user_id'   => $v,
                            'room_id'   => $roomId,
                            'types'     => 2,
                        ];
                    }
                    $roomInfo = Room::where('id',$roomId)->find();
                    if(!empty($createData) && !empty($roomInfo)){
                        (new RoomUser())->saveAll($createData);
                        // 在世男
                        $aliveMaleCount = self::where('family_id',$applyFamilyInfo['family_id'])->where('user_id','<>',0)->where('status',1)->where('gender',1)->count();
                        // 在世女
                        $aliveWomanCount = self::where('family_id',$applyFamilyInfo['family_id'])->where('user_id','<>',0)->where('status',1)->where('gender',0)->count();
                        // 去世男
                        $dieMaleCount = self::where('family_id',$applyFamilyInfo['family_id'])->where('user_id','<>',0)->where('status',0)->where('gender',1)->count();
                        // 去世女
                        $dieWomanCount = self::where('family_id',$applyFamilyInfo['family_id'])->where('user_id','<>',0)->where('status',0)->where('gender',0)->count();
                        Room::where('id',$roomId)->update([
                            'user_count'        => $roomInfo['user_count'] + $aliveMaleCount + $aliveWomanCount + $dieMaleCount + $dieWomanCount,
                            'alive_male_count'  => $roomInfo['alive_male_count'] + $aliveMaleCount,
                            'alive_woman_count' => $roomInfo['alive_woman_count'] + $aliveWomanCount,
                            'die_male_count'    => $roomInfo['die_male_count'] + $dieMaleCount,
                            'die_woman_count'   => $roomInfo['die_woman_count'] + $dieWomanCount,
                        ]);
                    }
                }

                self::where('family_id',$applyFamilyInfo['family_id'])->update(['is_max'=>0]);
                self::move($topLevelId,$familyInfo['id']);
                // 修改最上级 父id 跟辈分
                //self::where('id',$topLevelId)->update(['parent_id'=>$familyInfo['id'],'is_max'=>0]);
                self::dgtbInfo($topLevelId,$familyInfo['id']);

                // 修改家庭所有家庭组id
                self::where('family_id',$applyFamilyInfo['family_id'])->update(['family_id'=>$familyInfo['family_id']]);
            }

            FamilyTreeApply::where('id',$applyInfo['id'])->update([
                'status'=>$type
            ]);
            Db::commit();
            if(isset($applyFamilyInfo) && isset($applyFamilyInfo['family_id'])){
                self::delCache($applyFamilyInfo['family_id']);
            }
            if(isset($familyInfo['family_id'])){
                self::delCache($familyInfo['family_id']);
            }
            return true;
        }catch(Exception $e){
            Db::rollback();
            write_log($e->getMessage(),'审核加入家庭错误');
            return false;
        }
    }

    public static function dgtbInfo($topId,$parentId){
        $topInfo = self::where('id',$topId)->field('id,name,user_id,spouse_id,seniority')->find();

        if($topInfo['spouse_id'] == 0){
            return self::where('id',$topId)->update(['parent_id'=>$parentId,'is_max'=>0]);
        }
        $topPo = self::where('id',$topInfo['spouse_id'])->field('id,name,spouse_id')->find();

        $info = Db::name('family_tree as fm1')
            ->join('family_tree fm2','fm1.spouse_id = fm2.id')
            ->where('fm1.parent_id',$parentId)
            ->where('fm1.name',$topInfo['name'])
            ->where('fm2.name',$topPo['name'])
            ->field('fm1.id,fm1.name,fm1.user_id,fm1.spouse_id,fm1.seniority,fm1.parent_id,fm2.name as spouse_name,fm2.id as spouse_id')
            ->find();
        if(empty($info) || ($info['user_id'] != 0 && $topInfo['user_id'] != 0)){
            return self::where('id',$topId)->update(['parent_id'=>$parentId,'is_max'=>0]);
        }
        if($info['user_id'] != 0){
            self::where('id','IN',[$topInfo['id'],$topPo['id']])->delete();
            $list = self::where('parent_id',$topInfo['id'])->select();
            if($list->isEmpty()){
                return true;
            }
            foreach($list as $v){
                self::dgtbInfo($v['id'],$info['id']);
            }
        }else if($topInfo['user_id'] != 0){
            self::where('id',$info['id'])->update([
                //'name'  => $topInfo['name'],
                'user_id'=>$topInfo['user_id'],
                //'seniority' => $topInfo['seniority'],
                //'parent_id'=>$parentId
            ]);
            self::where('id','IN',[$topInfo['id'],$topPo['id']])->delete();
            $list = self::where('parent_id',$topInfo['id'])->select();
            if($list->isEmpty()){
                return true;
            }
            foreach($list as $v){
                self::dgtbInfo($v['id'],$info['id']);
            }
        }else{
            self::where('id','IN',[$topInfo['id'],$topPo['id']])->delete();
            $list = self::where('parent_id',$topInfo['id'])->select();
            if($list->isEmpty()){
                return true;
            }
            foreach($list as $v){
                self::dgtbInfo($v['id'],$info['id']);
            }
        }
    }
    /**
     * 递归修改辈分
     * @param $applyFamilyId  被修改用户ids
     * @param $toFaimlyId     父亲id （获取辈分用）
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function move($applyFamilyId,$toFaimlyId){
        $toFamilyInfo = self::where('parent_id',$toFaimlyId)->order('start_time','asc')->field('id,seniority')->find();
        if(empty($toFamilyInfo)){
            return ;
        }
        // 修改当前用户id辈分
        self::where('id','IN',$applyFamilyId)->update([
            'seniority' => $toFamilyInfo['seniority']
        ]);
        $ids = self::where('parent_id','IN',$applyFamilyId)->column('id');
        if(!empty($ids)){
            return self::move($ids,$toFamilyInfo['id']);
        }else{
            return ;
        }
    }

    /**
     * 获取辈分
     * @param $userId
     */
    public static function getSeniority($userId,$data=[]){
        $info = self::where('user_id',$userId)->field('id,family_id,seniority')->find();
        if(empty($info)){
            return $data;
        }
        $family = self::where('family_id',$info['family_id'])->where('parent_id',0)->where('gender',1)->field('id,seniority')->find();
        if(empty($family)){
            $family = self::where('family_id',$info['family_id'])->where('parent_id',0)->where('gender',1)->field('id,seniority')->find();
        }
        if(empty($family)){
            return $data;
        }
        $data[] = $family['seniority'];
        return self::dgSeniority($family['id'],$data);
    }

    public static function dgSeniority($familyId,$data){
        if(empty($familyId)){
            return $data;
        }
        $seniority = self::where('parent_id','IN',$familyId)->value('seniority');
        if(empty($seniority)){
            return $data;
        }
        $data[] = $seniority;
        $ids = self::where('parent_id','IN',$familyId)->column('id');
        return self::dgSeniority($ids,$data);
    }

    public static function getChildCount($ids,$count=0){
        if(empty($ids)){
            return $count;
        }
        $chilIds = self::where('parent_id','IN',$ids)->column('id');
        $spouseIds = self::where('spouse_id','IN',$ids)->column('id');
        if(!empty($spouseIds)){
            $chilIds2 = self::where('parent_id','IN',$spouseIds)->column('id');
            $chilIds = array_merge($chilIds,$chilIds2);
        }
        $count += count($chilIds);
        if(!empty($chilIds)){
            return self::getChildCount($chilIds,$count);
        }
        return $count;

    }

    /**
     * 查询家庭用户下面是否有入驻过得用户
     */
    public static function getChildZsyh($fid){
        if(empty($fid)){
            return false;
        }
        $count = self::where('id','IN',$fid)->where('user_id','<>',0)->count();
        if($count > 0){
            return true;
        }
        $parentId = self::where('parent_id','IN',$fid)->column('id');
        return self::getChildZsyh($parentId);
    }
}